package belpic.spring_data.web;

import java.io.Serializable;
import java.net.URI;
import java.util.List;

import javax.validation.Valid;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import belpic.spring_data.repository.CrudRepositoryList;

public abstract class CrudController<T,ID extends Serializable> {
	
	@RequestMapping(method=RequestMethod.POST)
	public ResponseEntity<T> post(@Valid T domainObject) {
		System.out.println("POST");
		getRepository().save(domainObject);

		//HttpHeaders http = buildHeadersWithLocation("/applications/{id}", application.getId());
		
		ResponseEntity<T> response = new ResponseEntity<T>(domainObject, HttpStatus.CREATED);
		return response;
	}

	private HttpHeaders buildHeadersWithLocation(String path, Object...uriVariableValues) {
		URI uri = ServletUriComponentsBuilder.fromCurrentServletMapping().path(path).buildAndExpand(uriVariableValues).toUri();
		HttpHeaders http = new HttpHeaders();
		http.setLocation(uri);
		return http;
	}
	
	@ResponseStatus(value=HttpStatus.OK)
	@RequestMapping(method=RequestMethod.PUT, value="/{id}")
	public String put(@Valid T application, @PathVariable Long id){
		System.out.println("PUT for " + id);
		getRepository().save(application);
		return "redirect:applications";
	}
	
	@RequestMapping(method=RequestMethod.GET, produces="application/json")
	public @ResponseBody List<T> get(){
		System.out.println("findAll");
		return getRepository().findAll();
	}
	
	@RequestMapping(method=RequestMethod.GET, value="/{id}")
	public @ResponseBody T getApplication(@PathVariable ID id){
		System.out.println("findAll");
		return getRepository().findOne(id);
	}
	
	@RequestMapping(method=RequestMethod.GET, value="/form")
	public ModelAndView getForm(){
		ModelAndView mav = new ModelAndView("application/form");
		mav.addObject("command", getDomainObject());
		return mav;
	}
	
	@ResponseStatus(value=HttpStatus.NO_CONTENT)
	@RequestMapping(value="/{id}", method=RequestMethod.DELETE)
	public void delete(@PathVariable ID id){
		System.out.println("DELETE");
		getRepository().delete(id);
	}
	
	abstract protected T getDomainObject();
	abstract protected CrudRepositoryList<T, ID> getRepository();
}
